package calao.storage;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

public class DumpInputStream
extends DataInputStream
{

	class DumpDataReader extends DataReader {
		@Override
		public boolean readBoolean() {
			try {
				return DumpInputStream.this.readBoolean();
			} 
			catch (IOException e) {
				throw new RuntimeException();
			}
		}
		@Override
		public double readDouble() {
			try {
				return DumpInputStream.this.readDouble();
			} 
			catch (IOException e) {
				throw new RuntimeException();
			}
		}
		@Override
		public int readInt() {
			try {
				return DumpInputStream.this.readInt();
			} 
			catch (IOException e) {
				throw new RuntimeException();
			}
		}
		@Override
		public long readLong() {
			try {
				return DumpInputStream.this.readLong();
			} 
			catch (IOException e) {
				throw new RuntimeException();
			}
		}
		@Override
		public String readString() {
			try {
				return DumpInputStream.this.readUTF();
			} 
			catch (IOException e) {
				throw new RuntimeException();
			}
		}		
	}

	public DumpInputStream(InputStream stream) 
	{
		super(stream);
	}

	public void restore(Storage storage) 
	throws IOException, UnknownBindingException
	{
		storage.clear();
		int tag;
		while ((tag=read())>0) {
			if (tag==1) {
				Table table = Table.getTable(readUTF());
				while (read()>0) {
					Record record = new Record(table);
					restore(record);
					storage.store(record);
				}
			}
			else {
				Sequence seq = Sequence.getSequence(readUTF());
				storage.setValue(seq, readInt());
			}
		}
	}

	void restore(Record record) 
	throws IOException, UnknownBindingException
	{
		while (read()>0) {
			Field field = record.table.getField(readUTF());
			Object[] values = new Object[read()];
			for (int i=0; i<values.length; i++) {
				Object value = null;
				switch (field.type.enumValue) {
				case INTEGER:
					value = readInt();
					break;
				case SHORT:
					value = readShort();
					break;
				case LONG:
					value = readLong();
					break;
				case DOUBLE:
					value = readDouble();
					break;
				case STRING:
					value = readUTF();
					break;
				case OBJECT:
					DumpDataReader reader = new DumpDataReader();
					value = reader.readObject();
					break;						
				}
				values[i] = value;
			}
			if (field.multiValued) record.directSet(field, values);
			else if (values.length>0) record.directSet(field, values[0]);
		}
	}

}
